﻿using System;
using System.Collections.Generic;

namespace Runtime.Models {

    /// <summary>
    /// 效果数据列表
    /// </summary>
    public interface IDFR_ReadOnlyBattleEffectListModelTD : IDFR_ReadOnlyListModel<IDFR_BattleEffectModelTD> {

        new IDFR_BattleEffectListModelTD AsReadWrite();

        IDFR_ReadOnlyBattleEffectListModelBase AsBase();
    }

    /// <summary>
    /// 效果数据列表
    /// </summary>
    public interface IDFR_BattleEffectListModelTD : IDFR_ReadOnlyBattleEffectListModelTD, IDFR_ListModel<IDFR_BattleEffectModelTD> {

        new IDFR_BattleEffectListModelBase AsBase();
    }

    [Implement(typeof(IDFR_ReadOnlyBattleEffectListModelTD))]
    [Implement(typeof(IDFR_ReadOnlyBattleEffectListModelBase))]
    [Implement(typeof(IDFR_ReadOnlyListModel<IDFR_BattleEffectModelTD>))]
    [Implement(typeof(IDFR_ReadOnlyListModel<IDFR_BattleEffectModelBase>))]
    [Implement(typeof(IDFR_BattleEffectListModelTD))]
    [Implement(typeof(IDFR_BattleEffectListModelBase))]
    [Implement(typeof(IDFR_ListModel<IDFR_BattleEffectModelTD>))]
    [Implement(typeof(IDFR_ListModel<IDFR_BattleEffectModelBase>))]
    internal sealed class DFR_BattleEffectListModelTD : DFR_ListModel<IDFR_BattleEffectModelTD>,
        IDFR_ReadOnlyBattleEffectListModelTD, IDFR_BattleEffectListModelTD,
        IDFR_ReadOnlyBattleEffectListModelBase, IDFR_BattleEffectListModelBase {

        public new IDFR_BattleEffectListModelTD AsReadWrite() => this;
        IDFR_BattleEffectListModelBase IDFR_ReadOnlyBattleEffectListModelBase.AsReadWrite() => this;
        IListData<IDFR_BattleEffectModelBase> IReadOnlyListData<IDFR_BattleEffectModelBase>.AsReadWrite() => this;
        IReadOnlyListData<IDFR_BattleEffectModelBase> IListData<IDFR_BattleEffectModelBase>.AsReadOnly() => this;
        IDFR_ReadOnlyBattleEffectListModelBase IDFR_ReadOnlyBattleEffectListModelTD.AsBase() => this;
        IDFR_BattleEffectListModelBase IDFR_BattleEffectListModelTD.AsBase() => this;

        public DFR_BattleEffectListModelTD() : base() {
            Updated += (index, oldValue, newValue) => m_Updated?.Invoke(index, oldValue, newValue);
            Added += (index, newValue) => m_Added?.Invoke(index, newValue);
            Removed += (index, oldValue) => m_Removed?.Invoke(index, oldValue);
            Cleared += () => m_Cleared?.Invoke();
        }

        protected override void Dispose() {
            m_Updated = null;
            m_Added = null;
            m_Removed = null;
            m_Cleared = null;
            base.Dispose();
        }

        IDFR_BattleEffectModelBase IReadOnlyList<IDFR_BattleEffectModelBase>.this[int index] => this[index];

        IDFR_BattleEffectModelBase IList<IDFR_BattleEffectModelBase>.this[int index] {
            get => this[index];
            set => this[index] = (IDFR_BattleEffectModelTD)value;
        }
        IDFR_BattleEffectModelBase IListData<IDFR_BattleEffectModelBase>.this[int index] {
            get => this[index];
            set => this[index] = (IDFR_BattleEffectModelTD)value;
        }

        private event IListDataUpdated<IDFR_BattleEffectModelBase>.UpdatedDelegate m_Updated;
        event IListDataUpdated<IDFR_BattleEffectModelBase>.UpdatedDelegate IListDataUpdated<IDFR_BattleEffectModelBase>.Updated {
            add => m_Updated += value;
            remove => m_Updated -= value;
        }

        private event IListDataAdded<IDFR_BattleEffectModelBase>.AddedDelegate m_Added;
        event IListDataAdded<IDFR_BattleEffectModelBase>.AddedDelegate IListDataAdded<IDFR_BattleEffectModelBase>.Added {
            add => m_Added += value;
            remove => m_Added -= value;
        }

        private event IListDataRemoved<IDFR_BattleEffectModelBase>.RemovedDelegate m_Removed;
        event IListDataRemoved<IDFR_BattleEffectModelBase>.RemovedDelegate IListDataRemoved<IDFR_BattleEffectModelBase>.Removed {
            add => m_Removed += value;
            remove => m_Removed -= value;
        }

        private event IListDataCleared<IDFR_BattleEffectModelBase>.ClearedDelegate m_Cleared;
        event IListDataCleared<IDFR_BattleEffectModelBase>.ClearedDelegate IListDataCleared<IDFR_BattleEffectModelBase>.Cleared {
            add => m_Cleared += value;
            remove => m_Cleared -= value;
        }

        IDFR_BattleEffectModelBase IReadOnlyListData<IDFR_BattleEffectModelBase>.Get(int index) => Get(index);

        IEnumerator<IDFR_BattleEffectModelBase> IEnumerable<IDFR_BattleEffectModelBase>.GetEnumerator() => GetEnumerator();

        bool IReadOnlyListData<IDFR_BattleEffectModelBase>.TryGet(int index, out IDFR_BattleEffectModelBase value) {
            if (TryGet(index, out var result)) {
                value = result;
                return true;
            }
            value = default;
            return false;
        }

        void IFixedLengthListData<IDFR_BattleEffectModelBase>.Update(int index, IDFR_BattleEffectModelBase value) => Update(index, (IDFR_BattleEffectModelTD)value);

        void IFixedLengthListData<IDFR_BattleEffectModelBase>.Update(int index, Action<IDFR_BattleEffectModelBase> updater) => Update(index, updater);

        int IList<IDFR_BattleEffectModelBase>.IndexOf(IDFR_BattleEffectModelBase item) => IndexOf((IDFR_BattleEffectModelTD)item);

        void IList<IDFR_BattleEffectModelBase>.Insert(int index, IDFR_BattleEffectModelBase item) => Insert(index, (IDFR_BattleEffectModelTD)item);

        void ICollection<IDFR_BattleEffectModelBase>.Add(IDFR_BattleEffectModelBase item) => Add((IDFR_BattleEffectModelTD)item);

        bool ICollection<IDFR_BattleEffectModelBase>.Contains(IDFR_BattleEffectModelBase item) => Contains((IDFR_BattleEffectModelTD)item);

        void ICollection<IDFR_BattleEffectModelBase>.CopyTo(IDFR_BattleEffectModelBase[] array, int arrayIndex) {
            foreach (var item in this) {
                array[arrayIndex++] = item;
            }
        }

        bool ICollection<IDFR_BattleEffectModelBase>.Remove(IDFR_BattleEffectModelBase item) => Remove((IDFR_BattleEffectModelTD)item);
    }
}
